#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
#include <QDebug>
#include <QMessageBox>
#include <QColorDialog>
#include <QFileDialog>
#include <QCryptographicHash>
#include <QTimer>
#include <QDateTime>

MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent), ui(new Ui::MainWindow)
{
    initWindow();

    ui->progressBar->setValue(0);

    // 点击打开按钮
    connect(ui->actionNew, &QAction::triggered, [=] {
        // 初始化显示
        ui->filename->setText("");
        ui->filesize->setText("");
        ui->md5sumContent->setText("");
        ui->sha256HashLabel->setText("");
        ui->progressBar->setMinimum(0);
        ui->progressBar->setValue(0);

        // 参数1：父亲，参数2：标题，参数3：默认打开路径（不指定的话，则默认打开程序所在的目录）,参数4：过滤文件格式
        auto filename = QFileDialog::getOpenFileName(this, "打开文件", getLastPath());
        if (filename.isEmpty()) {
            return;
        }

        // 显示文件名
        QFileInfo f(filename);
        if (!f.exists()) {
            QMessageBox::critical(this, "错误", "文件不存在！");
            return;
        }

        ui->filename->setText(f.fileName());

        // 计算md5并显示
        QFile theFile(filename);
        if (theFile.size() == 0) {
            ui->md5sumContent->setText("");
            QMessageBox::critical(this, "错误", "文件为空！");
            return;
        }

        ui->progressBar->setMaximum(theFile.size());
        ui->filesize->setText(QString::number(theFile.size()));

        theFile.open(QIODevice::ReadOnly);
        QCryptographicHash hash(QCryptographicHash::Md5);
        QCryptographicHash sha256(QCryptographicHash::Sha256);
        size_t filesize = 0;

        while (true) {
            auto ba = theFile.read(1024 * 1024 * 10);
            if (ba.length() > 0) {
                filesize += ba.length();
                ui->progressBar->setValue(filesize);
                hash.addData(ba);
                sha256.addData(ba);
            } else break;
        }
        theFile.close();
        if (filesize == theFile.size()) {
            ui->md5sumContent->setText(hash.result().toHex().constData());
            ui->sha256HashLabel->setText(sha256.result().toHex().constData());
        } else {
            ui->md5sumContent->setText("");
            ui->sha256HashLabel->setText("");
            QMessageBox::critical(this, "错误", "读取文件错误！");
        }
        setLastPath(f.absolutePath());
    });

    // 关于 弹框
    connect(ui->actionAbout, &QAction::triggered, [=] {
        QMessageBox::information(this, "关于", "文件MD5计算器\n制作人：YH\n版本：v1.0");
    });
}

MainWindow::~MainWindow()
{
    // 保存到文件
    if (!lastPath.isEmpty()) {
        QString runPath = QCoreApplication::applicationDirPath();
        QFile configFile(runPath + "/config.txt");
        if (configFile.open(QIODevice::WriteOnly)) {
            configFile.write(lastPath.toUtf8());
            configFile.close();
        }
    }
    delete ui;
}

void MainWindow::initWindow()
{
    ui->setupUi(this);
    setWindowTitle("文件MD5计算器");

    QString runPath = QCoreApplication::applicationDirPath();

    setWindowIcon(QIcon(":/image/favicon.ico"));
    ui->actionNew->setIcon(QIcon(":/image/open.ico"));

    // 设置用户信息
    username = QDir::home().dirName();
    auto statusBarUserLabel = new QLabel(this);
    statusBarUserLabel->setText("当前用户：" + username + "   ");
    ui->statusbar->addPermanentWidget(statusBarUserLabel);

    // 状态栏系统时间
    statusBarTimeLabel = new QLabel(this);
    ui->statusbar->addPermanentWidget(statusBarTimeLabel);

    // 定时更新时间
    auto timer = new QTimer(this);
    timer->start(1000);
    connect(timer, &QTimer::timeout, this, &MainWindow::updateStatusBarTimeLabel);
}

void MainWindow::updateStatusBarTimeLabel()
{
    auto currentTime = QDateTime::currentDateTime();
    auto currentTimeStr = currentTime.toString("yyyy-MM-dd hh:mm:ss");
    statusBarTimeLabel->setText("系统时间：" + currentTimeStr);
}

QString MainWindow::getLastPath()
{
    if (!lastPath.isEmpty()) {
        return lastPath;
    }
    QString runPath = QCoreApplication::applicationDirPath();
    QFile configFile(runPath + "/config.txt");
    if (!configFile.exists()) {
        return getUserPath();
    } else {
        if (configFile.open(QIODevice::ReadOnly)) {
            auto line = configFile.readLine();
            configFile.close();
            return line;
        } else {
            return getUserPath();
        }
    }
}

void MainWindow::setLastPath(const QString &path)
{
    lastPath = path;
}

QString MainWindow::getUserPath()
{
#ifdef _WIN32
    return QString("C:\\Users\\" + username + "\\Desktop");
#else
    return QString("/home/" + username + "/Desktop");
#endif
}
